const { ccclass, property } = cc._decorator;

@ccclass
export class PoolManager {
    static _instance: PoolManager;
    static get Instance() {
        if (!this._instance) {
            this._instance = new PoolManager();
        }
        return this._instance;
    }

    private _pool: any = {}

    public PreloadPrefab(prefab: cc.Prefab, count: number) {
        let name = prefab.name;
        if (!this._pool.hasOwnProperty(name)) {
            this._pool[name] = new cc.NodePool();
        }

        if (this._pool[name].size() >= count) return;

        const finalCount = count - this._pool[name].size();

        for (let i = 0; i < finalCount; i++) {
            this._pool[name].put(cc.instantiate(prefab));
        }
    }

    public GetNode(prefab: cc.Prefab, parent: cc.Node) {
        let name = prefab.name;
        let node = null;
        if (this._pool.hasOwnProperty(name)) {
            let pool = this._pool[name];
            if (pool.size() > 0) {
                node = pool.get();
            } else {
                node = cc.instantiate(prefab);
            }
        } else {
            let pool = new cc.NodePool();
            this._pool[name] = pool;

            node = cc.instantiate(prefab);
        }
        
        node.scale = cc.Vec3.ONE;
        node.parent = parent;
        node.position = cc.Vec3.ZERO;
        node.active = true;

        return node;
    }

    public PutNode(node: cc.Node) {
        if (!node) return;
        let pool = null;
        if (this._pool.hasOwnProperty(node.name)) {
            pool = this._pool[node.name];
        } else {
            pool = new cc.NodePool();
            this._pool[node.name] = pool;
        }

        pool.put(node);
    }

    public ClearPool(name: string) {
        if (this._pool.hasOwnProperty(name)) {
            let pool = this._pool[name];
            pool.clear();
        }
    }
}